package hu.ikti.oamadmin.beans.serviceprofile;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import javax.persistence.Query;

import hu.ikti.oamadmin.beans.BaseBean;
import hu.ikti.oamadmin.types.entities.Bundle;
import hu.ikti.oamadmin.types.entities.ByteCode;
import hu.ikti.oamadmin.types.entities.Resource;
import hu.ikti.oamadmin.types.entities.Service;
import hu.ikti.oamadmin.types.entities.ServiceProfile;

import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Begin;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Out;
import org.jboss.seam.faces.FacesMessages;
import org.jboss.seam.international.StatusMessage.Severity;
import org.primefaces.model.DualListModel;
import org.richfaces.event.UploadEvent;
import org.richfaces.model.UploadItem;

@Name("editServiceprofileBean")
@Scope(ScopeType.CONVERSATION)
public class EditServiceprofileBean extends BaseBean implements Serializable {

	private static final long serialVersionUID = 1L;

	@In(create = true)
	@Out
	private ServiceProfile serviceprofile;

	@In(required = false)
	private List<ServiceProfile> serviceprofileList;

	private List<Service> sourceServiceList;
	private List<Service> targetServiceList;

	private DualListModel<Service> serviceDualList;
	
	@Out(required = false, value = "selectedServices")
	private List<Service> selectedServices;

	@Begin(pageflow = "editServiceprofile", join = true)
	public String newServiceprofile() {
		return "start";
	}
	
	public String toEditResources() {
		if (serviceprofile.getId() != null) {
			serviceprofile = (ServiceProfile) entityManager
					.createQuery(
							"select serviceprofile from Serviceprofile serviceprofile "
									+ "left outer join serviceprofile.resources "
									+ "where serviceprofile.id = :id")
					.setParameter(0, serviceprofile.getId()).getSingleResult();
		}
		return "toEditResources";
	}
	
	@Begin(pageflow = "editServiceprofile", join = true)
	public String editServiceprofile() {
		try {
			serviceprofile = entityManager.find(ServiceProfile.class,
					serviceprofile.getId());

			targetServiceList = serviceprofile.getServices();

			sourceServiceList = new ArrayList<Service>();

			Query query = entityManager
					.createQuery("select service from Service service");
			List<?> results = query.getResultList();
			for (Object object : results) {
				Service service = (Service) object;
				if (!targetServiceList.contains(service)) {
					sourceServiceList.add(service);
				}
			}

			serviceDualList = new DualListModel<Service>(sourceServiceList,
					targetServiceList);

			return "editServices";
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	public String toSelectServices() {
		targetServiceList = new ArrayList<Service>();
		sourceServiceList = new ArrayList<Service>();

		Query query = entityManager
				.createQuery("select service from Service service");
		List<?> results = query.getResultList();
		for (Object object : results) {
			sourceServiceList.add((Service) object);
		}

		serviceDualList = new DualListModel<Service>(sourceServiceList,
				targetServiceList);

		return "toSelectServices";
	}

	public String saveServiceprofile() {
		try {
			if (serviceprofile.getId() != null) {
				serviceprofile = (ServiceProfile) entityManager.find(
						ServiceProfile.class, serviceprofile.getId());
			} else {
				entityManager.persist(serviceprofile);
			}

			List<Bundle> oldBundles = serviceprofile.getBundles();
			for (Bundle bundle : oldBundles) {
				bundle = (Bundle) entityManager.find(Bundle.class,
						bundle.getId());
				entityManager.remove(bundle);
			}

			serviceprofile.getBundles().clear();

			serviceprofile.getServices().clear();

			targetServiceList = serviceDualList.getTarget();
			for (Service service : targetServiceList) {
				serviceprofile.getServices().add(service);
				for (Bundle bundle : service.getBundles()) {
					Bundle cloneBundle = new Bundle();
					cloneBundle.setBundleData(bundle.getBundleData());
					cloneBundle.setServiceProfile(serviceprofile);
					cloneBundle.setParent(bundle);
					entityManager.persist(cloneBundle);
					serviceprofile.getBundles().add(cloneBundle);
				}
			}

			serviceprofile = entityManager.merge(serviceprofile);

			if (!serviceprofileList.contains(serviceprofile)) {
				serviceprofileList.add(serviceprofile);
			}

			FacesMessages.instance().add(Severity.INFO, "Saved: #0 #1",
					serviceprofile.getName(), serviceprofile.getDescription());

			return "done";
		} catch (Exception e) {
			e.printStackTrace();
			FacesMessages.instance().add(Severity.ERROR, "System error!");
			return null;
		}
	}

	public void cancel() {
		FacesMessages.instance().add(Severity.WARN, "Transaction canceled!");
	}

	public DualListModel<Service> getServiceDualList() {
		return serviceDualList;
	}

	public void setServiceDualList(DualListModel<Service> serviceDualList) {
		this.serviceDualList = serviceDualList;
	}
	
	public void uploadListener(UploadEvent event) throws Exception {
		UploadItem item = event.getUploadItem();
		String[] parsedFileName = item.getFileName().split("\\.");
		Resource resource = new Resource();
		ByteCode byteCode = new ByteCode();
		byteCode.setBytes(item.getData());
		resource.setByteCode(byteCode);
		resource.setExtension(parsedFileName[parsedFileName.length - 1]);
		resource.setFileName(item.getFileName());
		resource.setUploadTime(Calendar.getInstance().getTime());
		resource.setSize(item.getFileSize());
		serviceprofile.getResources().add(resource);
	}

	public String toSummary() {
		selectedServices = new ArrayList<Service>();
		targetServiceList = serviceDualList.getTarget();
		for (Service s : targetServiceList)
			selectedServices.add(s);
	
		return "tosummary";
	}

}
